package com.magic233.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.magic233.entity.*;
import com.magic233.mapper.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * ClassName: OrdersServiceImpl
 * Description:
 * date: 2021/5/30 0:17
 * author: zouyuan
 */
@Service
public class OrdersServiceImpl implements OrdersService {

    @Autowired
    private OrdersMapper ordersMapper;
    @Autowired
    private LogsService logsService;
    @Autowired
    private WorkersMapper workersMapper;
    @Autowired
    private OrderCommentsMapper orderCommentsMapper;
    @Autowired
    private MessageService messageService;
    @Autowired
    private UsersMapper usersMapper;
    @Autowired
    private WorkTypeMapper workTypeMapper;

    private final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");

    @Override
    @Transactional
    public int addOrder(Users user, Orders order) {
        Long id = new Date().getTime();
        String starttime = simpleDateFormat.format(id);
        order.setId(id);
        order.setUid(user.getId());
        order.setWid((long) 0);
        order.setStarttime(starttime);
        order.setUpdatetime(starttime);
        order.setStatus("未派单");
        int re = ordersMapper.insert(order);
        if (re == 1) {
            String thing = null;
            try {
                String orderStr = new ObjectMapper().writeValueAsString(order);
                thing = "用户：{" + user.getPhone() + "--" + user.getUsername() + "}提交了工单：" + orderStr;
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            logsService.addLog(thing);
        }
        return re;
    }


    @Override
    @Transactional
    public int removeOrder(Users user, Long id) {
        Orders o = new Orders();
        Long time = new Date().getTime();
        String updatetime = simpleDateFormat.format(time);
        o.setId(id);
        o.setStatus("用户已撤单");
        o.setUpdatetime(updatetime);
        int re = ordersMapper.updateByPrimaryKeySelective2(o, user.getId());
        if (re == 1) {
            String thing = "用户：{" + user.getPhone() + "--" + user.getUsername() + "}撤销了工单：" + id;
            logsService.addLog(thing);
        }
        return re;
    }

    //管理员指派工单
    @Override
    @Transactional
    public int sendOrder(Users user, Long id, Long wid) {

        //获取指派的工人
        Workers worker = workersMapper.selectByPrimaryKey(wid);
        if (worker != null) {
            Orders o = new Orders();
            Long time = new Date().getTime();
            String updatetime = simpleDateFormat.format(time);
            o.setId(id);
            o.setWid(wid);
            o.setStatus("管理员已派单");
            o.setType(worker.getType());
            o.setUpdatetime(updatetime);
            int re = ordersMapper.updateByPrimaryKeySelective(o);
            if (re == 1) {
                String thing = "管理员：{" + user.getPhone() + "--" + user.getUsername() + "}指派了工单：" + id + " 维修人员：" + wid;
                logsService.addLog(thing);
            }
            return re;
        } else {
            return 0;
        }

    }

    //管理员重新指派工单
    @Override
    @Transactional
    public int againSendOrder(Users user, Long id, Long wid) {

        //获取指派的工人
        Workers worker = workersMapper.selectByPrimaryKey(wid);
        if (worker != null) {
            Orders o = new Orders();
            Long time = new Date().getTime();
            String updatetime = simpleDateFormat.format(time);
            o.setId(id);
            o.setWid(wid);
            o.setStatus("管理员已派单");
            o.setType(worker.getType());
            o.setUpdatetime(updatetime);
            int re = ordersMapper.updateByPrimaryKeySelective4(o);
            if (re == 1) {
                String thing = "管理员：{" + user.getPhone() + "--" + user.getUsername() + "}重新指派了工单：" + id + " 维修人员：" + wid;
                logsService.addLog(thing);
            }
            return re;
        } else {
            return 0;
        }

    }

    //维修人员申请退单
    @Override
    public int cancelOrder(Users user, Long id, String workerReason) {
        Orders o = new Orders();
        Long time = new Date().getTime();
        String updatetime = simpleDateFormat.format(time);
        o.setId(id);
        o.setStatus("工人申请退单");
        o.setUpdatetime(updatetime);
        o.setWorkerreason(workerReason);
        int re = ordersMapper.updateByPrimaryKeySelective3(o, user.getId());
        if (re == 1) {
            String thing = "维修人员：{" + user.getPhone() + "--" + user.getUsername() + "}申请取消工单：" + id;
            logsService.addLog(thing);

            String content = "维修人员<" + user.getUsername() + ">申请取消工单<" + id + ">,退单原因<" + workerReason + ">,请等待管理员处理。";
            Long uid = ordersMapper.selectByPrimaryKey(id).getUid();
            messageService.sendMessage(Long.valueOf(1), uid, content);
        }
        return re;
    }

    //维修人员接单
    @Override
    public int acceptOrder(Users user, Long id) {
        Orders o = new Orders();
        Long time = new Date().getTime();
        String updatetime = simpleDateFormat.format(time);
        o.setId(id);
        o.setStatus("工人已接单");
        o.setUpdatetime(updatetime);
        int re = ordersMapper.updateByPrimaryKeySelective3(o, user.getId());
        if (re == 1) {
            String thing = "维修人员：{" + user.getPhone() + "--" + user.getUsername() + "}接受工单：" + id;
            logsService.addLog(thing);

            Orders o2 = ordersMapper.selectByPrimaryKey(o.getId());
            if (o2.getWxMessageOpen() != null && o2.getWxMessageOpen().equals("启用")) {
                System.out.println("启用微信推送");
                Users user1 = usersMapper.selectByPrimaryKey(o2.getUid());//申报人
                if (user1.getOpenid() != null && !"".equals(user1.getOpenid())) {
                    messageService.sendWeixinMessage1(user1, user, o2);
                }
            } else {
                System.out.println("关闭消息推送");
            }
        }
        return re;
    }

    //管理员同意退单申请
    @Override
    public int handOrderYes(Users user, Long id) {
        Orders o = new Orders();
        Long time = new Date().getTime();
        String updatetime = simpleDateFormat.format(time);
        o.setId(id);
        o.setStatus("工人已退单");
        o.setUpdatetime(updatetime);
        int re = ordersMapper.updateByPrimaryKeySelective4(o);
        if (re == 1) {
            String thing = "管理人员：{" + user.getPhone() + "--" + user.getUsername() + "}同意取消工单：" + id;
            logsService.addLog(thing);

            Orders tempOrder = ordersMapper.selectByPrimaryKey(id);
            Long wid = tempOrder.getWid();
            String content = "管理员<" + user.getUsername() + ">同意工单编号<" + id + ">的退单申请。";
            messageService.sendMessage(Long.valueOf(1), wid, content);

            Long uid = tempOrder.getUid();
            messageService.sendMessage(Long.valueOf(1), uid, content);
        }
        return re;
    }

    //管理员拒绝退单申请
    @Override
    public int handOrderNo(Users user, Long id, String adminReason) {
        Orders o = new Orders();
        Long time = new Date().getTime();
        String updatetime = simpleDateFormat.format(time);
        o.setId(id);
        o.setStatus("工人已接单");
        o.setUpdatetime(updatetime);
        o.setAdminreason(adminReason);
        int re = ordersMapper.updateByPrimaryKeySelective4(o);
        if (re == 1) {
            String thing = "管理人员：{" + user.getPhone() + "--" + user.getUsername() + "}拒绝取消工单：" + id;
            logsService.addLog(thing);

            Orders tempOrder = ordersMapper.selectByPrimaryKey(id);
            Long wid = tempOrder.getWid();
            String content = "管理员<" + user.getUsername() + ">拒绝工单编号<" + id + ">的退单申请。拒绝理由<" + adminReason + ">。";
            messageService.sendMessage(Long.valueOf(1), wid, content);

            Long uid = tempOrder.getUid();
            messageService.sendMessage(Long.valueOf(1), uid, content);

        }
        return re;
    }


    //维修人员确认维修完成
    @Override
    public int workerCompleteOrder(Users user, Long id, String consumable, String imgsfileids2) {
        Orders o = new Orders();
        Long time = new Date().getTime();
        String updatetime = simpleDateFormat.format(time);
        o.setId(id);
        o.setStatus("工人已完成");
        o.setConsumable(consumable);
        o.setImgsfileids2(imgsfileids2);
        o.setUpdatetime(updatetime);
        int re = ordersMapper.updateByPrimaryKeySelective5(o, user.getId());
        if (re == 1) {
            String thing = "维修人员：{" + user.getPhone() + "--" + user.getUsername() + "}确认维修完成：" + id;
            logsService.addLog(thing);

            Orders tempOrder = ordersMapper.selectByPrimaryKey(id);
            Long uid = tempOrder.getUid();
            String reason = tempOrder.getReason();
            String content = "您的工单<" + id + ">维修内容<" + reason + ">已经完成，请及时进行确认。";
            messageService.sendMessage(Long.valueOf(1), uid, content);

            Orders o2 = ordersMapper.selectByPrimaryKey(o.getId());
            if (o2.getWxMessageOpen() != null && o2.getWxMessageOpen().equals("启用")) {
                System.out.println("启用消息推送");
                Users user1 = usersMapper.selectByPrimaryKey(uid);//申报人
                if (user1.getOpenid() != null && !"".equals(user1.getOpenid())) {
                    messageService.sendWeixinMessage2(user1, user, o2);
                }
            } else {
                System.out.println("关闭消息推送");
            }
        }
        return re;
    }

    //用户确认维修完成
    @Transactional
    @Override
    public int userCompleteOrder(Users user, Long id, String comment, Double score1, Double score2, Double score3) {
        int re = 0;
        int re2 = 0;
        Orders o = new Orders();
        Long time = new Date().getTime();
        String updatetime = simpleDateFormat.format(time);
        o.setId(id);
        o.setStatus("已完成");
        o.setUpdatetime(updatetime);
        re = ordersMapper.updateByPrimaryKeySelective6(o, user.getId());
        if (re == 1) {
            OrderComments orderComments = new OrderComments();
            orderComments.setId(id);
            orderComments.setComment(comment);
            orderComments.setScore1(score1);
            orderComments.setScore2(score2);
            orderComments.setScore3(score3);
            re2 = orderCommentsMapper.insert(orderComments);
            if (re2 == 1) {
                String thing = "用户：{" + user.getPhone() + "--" + user.getUsername() + "}确认维修完成：" + id;
                logsService.addLog(thing);
            }
        }
        return re2;
    }

    //查询工单
    @Override
    public Map<Object, Object> selectOrders(Orders order, Integer pageNum, Integer pageSize) {
        System.out.println(pageNum);
        System.out.println(pageSize);
        if (pageNum != null && pageSize != null) {
            System.out.println("设置分页");
            PageHelper.startPage(pageNum, pageSize);
        }

        Page<Orders> orders = ordersMapper.selectOrders(order);
        long total = orders.getTotal();
        Map<Object, Object> map = new HashMap<>();
        map.put("orders", orders);
        map.put("total", total);
        return map;
    }

    @Override
    public Long selectCount(Orders order) {
        Long count = ordersMapper.selectCount(order);
        return count;
    }

    //管理员撤单
    @Override
    public int adminRemoveOrder(Users user, Long id) {
        Orders o = new Orders();
        Long time = new Date().getTime();
        String updatetime = simpleDateFormat.format(time);
        o.setId(id);
        o.setStatus("管理员已撤单");
        o.setUpdatetime(updatetime);
        int re = ordersMapper.updateByPrimaryKeySelective7(o);
        if (re == 1) {
            String thing = "管理员：{" + user.getPhone() + "--" + user.getUsername() + "}撤销了工单：" + id;
            logsService.addLog(thing);

            Orders tempOrder = ordersMapper.selectByPrimaryKey(id);
            Long uid = tempOrder.getUid();
            Long wid = tempOrder.getWid();
            String content = "管理员<" + user.getUsername() + ">撤销了您的工单，工单编号<" + id + ">。";
            messageService.sendMessage(Long.valueOf(1), uid, content);
            if (wid != 0) {
                messageService.sendMessage(Long.valueOf(1), wid, content);
            }
        }
        return re;
    }

    //工人设置备注
    @Override
    public int setWorkernote(Users user, Long id, String workernote) {
        Orders orders = new Orders();
        orders.setId(id);
        orders.setWorkernote(workernote);

        int re = ordersMapper.updateByPrimaryKeySelective8(orders, user.getId());
        if (re == 1) {
            String thing = "维修人员：{" + user.getPhone() + "--" + user.getUsername() + "}添加了备注：" + id;
            logsService.addLog(thing);
        }
        return re;
    }

    //工人设置标记
    @Transactional
    @Override
    public boolean mark(Users user, Long[] ids) {
        boolean flag = true;
        String idsStr = "";
        for (int i = 0; i < ids.length; i++) {
            idsStr += ids[i] + "  ";
            int mark = ordersMapper.mark(ids[i], user.getId());
            if (mark == 1) {
                continue;
            } else {
                flag = false;
                break;
            }
        }
        if (flag == true) {
            String thing = "维修人员：{" + user.getPhone() + "--" + user.getUsername() + "}添加了标记：" + idsStr;
            logsService.addLog(thing);
        }
        return flag;
    }


    //工人设置标记
    @Transactional
    @Override
    public boolean cancelMark(Users user, Long[] ids) {
        boolean flag = true;
        String idsStr = "";
        for (int i = 0; i < ids.length; i++) {
            idsStr += ids[i] + "  ";
            int mark = ordersMapper.cancelMark(ids[i], user.getId());
            if (mark == 1) {
                continue;
            } else {
                flag = false;
                break;
            }
        }
        if (flag == true) {
            String thing = "维修人员：{" + user.getPhone() + "--" + user.getUsername() + "}取消了标记：" + idsStr;
            logsService.addLog(thing);
        }
        return flag;
    }

    @Override
    public Object orderStatistical(Orders order) {
        //维修类别及查询时间范围
        Set<String> types = new TreeSet<String>();
        Set<String> dates = new TreeSet<String>();

        //所有类别报单数量及完成数量
        long acceptnumAll = 0;
        long completenumAll = 0;

        //按日查询所有维修类别接单数量，完成数量，包含已删除
        List<OrderStatistical> orderStatisticals = ordersMapper.orderStatistical(order);

        //工单按维修类别分组统计，便于前端处理
        Map<String, List<OrderStatistical>> collect = orderStatisticals.stream().collect(Collectors.groupingBy(a -> a.getType()));
        Set<Map.Entry<String, List<OrderStatistical>>> entries = collect.entrySet();
        List<OrderStatistical> orderStatisticalsGroupByType = new ArrayList<>();

        //按照维修类别遍历工单
        for (Map.Entry<String, List<OrderStatistical>> entry : entries) {
            String key = entry.getKey();
            types.add(key);
            long acceptnum = 0;
            long completenum = 0;
            for (OrderStatistical orderStatistical : entry.getValue()) {
                acceptnum += orderStatistical.getAcceptnum();
                completenum += orderStatistical.getCompletenum();
                dates.add(orderStatistical.getDate());
            }
            OrderStatistical tmp = new OrderStatistical();
            tmp.setType(key);
            tmp.setAcceptnum(acceptnum);
            tmp.setCompletenum(completenum);

            //计算完成率
            if(acceptnum == 0){
                tmp.setPercentage("0.00%");
            }else {
                tmp.setPercentage(String.format("%.2f",(double) completenum / (double) acceptnum * 100) + "%");
            }
            orderStatisticalsGroupByType.add(tmp);
            acceptnumAll += acceptnum;
            completenumAll += completenum;
        }
        //按照完成率排序
        Collections.sort(orderStatisticalsGroupByType);

        OrderStatistical tmp = new OrderStatistical();
        tmp.setType("总计");
        tmp.setAcceptnum(acceptnumAll);
        tmp.setCompletenum(completenumAll);
        if(acceptnumAll == 0){
            tmp.setPercentage("0.00%");
        }else {
            tmp.setPercentage(String.format("%.2f",(double) completenumAll / (double) acceptnumAll * 100) + "%");
        }
        orderStatisticalsGroupByType.add(tmp);

        Map<String,Object> result = new HashMap<>();
        result.put("orderStatisticals",orderStatisticals);
        result.put("orderStatisticalsGroupByType",orderStatisticalsGroupByType);
        result.put("types",types);
        result.put("dates",dates);
        return result;
    }


    @Override
    public List<Workers> workerStatistical() {
        List<Workers> workers1 = ordersMapper.workerStatistical();
        List<Workers> workers2 = ordersMapper.workerScore();
        for (int i = 0; i < workers1.size(); i++) {
            //工人已删除
            if (workers1.get(i).getDeleted() == 1) {
                workers1.get(i).setUsername(workers1.get(i).getUsername() + "(已删除)");
            }
            //计算完成率
            if(workers1.get(i).getAcceptnum() == 0){
                workers1.get(i).setPercentage("0.00%");
            }else {
                workers1.get(i).setPercentage(String.format("%.2f",(double) workers1.get(i).getCompletenum() / (double) workers1.get(i).getAcceptnum() * 100) + "%");
            }
            for (int j = 0; j < workers2.size(); j++) {
                if (workers1.get(i).getId().equals(workers2.get(j).getId())) {
                    DecimalFormat df = new DecimalFormat("#.00");
                    workers1.get(i).setScore1(Double.valueOf(df.format(workers2.get(j).getScore1())));
                    workers1.get(i).setScore2(Double.valueOf(df.format(workers2.get(j).getScore2())));
                    workers1.get(i).setScore3(Double.valueOf(df.format(workers2.get(j).getScore3())));
                    break;
                }
            }
        }
        Collections.sort(workers1);
        return workers1;
    }

    @Override
    public Map<Object, Object> selectDeptOrders(Users user, Orders order, Integer pageNum, Integer pageSize) {
        System.out.println(pageNum);
        System.out.println(pageSize);
        if (pageNum != null && pageSize != null) {
            System.out.println("设置分页");
            PageHelper.startPage(pageNum, pageSize);
        }

        String dept = user.getDept();
        Page<Orders> orders = ordersMapper.selectDeptOrders(order, dept);
        long total = orders.getTotal();
        Map<Object, Object> map = new HashMap<>();
        map.put("orders", orders);
        map.put("total", total);
        return map;
    }

    @Override
    public Map<Object, Object> selectOrdersWarn(Orders order, Integer pageNum, Integer pageSize) {
        System.out.println(pageNum);
        System.out.println(pageSize);
        if (pageNum != null && pageSize != null) {
            System.out.println("设置分页");
            PageHelper.startPage(pageNum, pageSize);
        }

        Page<Orders> orders = ordersMapper.selectOrdersWarn(order);
        long total = orders.getTotal();
        Map<Object, Object> map = new HashMap<>();
        map.put("orders", orders);
        map.put("total", total);
        return map;
    }

    @Override
    @Transactional
    public int systemAutoConfirm(Long id, Long uid, Long wid) {
        Long time = new Date().getTime();
        String updatetime = simpleDateFormat.format(time);
        Orders order = new Orders();
        order.setId(id);
        order.setStatus("已完成");
        order.setUpdatetime(updatetime);
        int re = ordersMapper.systemAutoConfirm(order);
        if (re == 1) {
            String thing = "工单编号<" + id + ">超时三天未确认,系统自动确认完成";
            logsService.addLog(thing);

            String content = "因超时三天未确认，系统自动确认完成了您的工单，工单编号<" + id + ">。";
            messageService.sendMessage(Long.valueOf(1), uid, content);

            return re;
        }
        return 0;
    }

    @Override
    public int updateOrderStatusByWorkerDisable(Orders orders) {
        int re = ordersMapper.updateOrderStatusByWorkerDisable(orders);
        return re;
    }
}
